#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import os
from pathlib import Path
import time,datetime
from ark_trade.ark_email import ark_email_spider
from ark_webholding.ark_holding import ark_webholding_spider
from ark_run_sql.run_sql import run_sql
from ark_fundflow.ark_fundflow import ark_fundflow_spider

import smtplib
from email.mime.text import MIMEText

import socket
from settings import my_settings
import requests
import json
import pymysql
from tqdm import tqdm


def log_process(log_path,log_rank):
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)  # or whatever
    handler = logging.FileHandler(log_path, 'w', 'utf-8')  # or whatever
    handler.setFormatter(
        logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'))  # or whatever
    logger.addHandler(handler)
    return logger

def send_email(subject,email_content_list,logger,logger_info,receiver):
    # 发送邮件相关参数
    smtpserver = 'smtp.mxhichina.com'  # 发件服务器
    port = 25  # 端口
    sender = 'zoey.yang@tradego8.com'  # 发件人邮箱
    psw = 'a123456.'  # 发件人密码
    # receiver = "zoey.yang@tradego8.com"       # 单个接收人
    # receiver = ["zoey.yang@tradego8.com", "tradego_ark@163.com"]

    # 编辑邮件内容
    email_content_list=['<p>'+line+'</p>' for line in email_content_list]
    body = ''.join(email_content_list)  # 定义邮件正文为html
    msg = MIMEText(body, 'html', 'utf-8')
    msg['from'] = sender
    # msg['to'] = receiver
    msg['to'] = ";".join(receiver)
    msg['subject'] = subject

    try:
        # 发送邮件
        smtp=smtplib.SMTP_SSL(smtpserver, 465)  # 启用SSL发信, 端口一般是465
        # smtp = smtplib.SMTP()
        # smtp.connect(smtpserver)    # 链接服务器
        smtp.login(sender, psw)     # 登录
        smtp.sendmail(sender, receiver, msg.as_string())  # 发送
        smtp.quit()             # 关闭
    except smtplib.SMTPException:
        logger.error('===%s 邮件发送失败===',logger_info)

def get_api(logger,info):
    logger.info('=======%s模块响应api，更新生产缓存',info)
    temp_today_str = str(time.strftime('%Y%m%d', time.localtime()))
    api_url = 'http://cloudapi.iqdii.com/arkTracking/ark/deleteArkCache?ark=' + temp_today_str

    response = requests.get(url=api_url)
    if response.status_code != 200:
        logger.error('===api请求错误 接口请求生产http响应状态码:%s===', response.status_code)
    else:
        logger.info('===接口请求生产http响应状态码:%s', response.status_code)
    api_content = response.content
    if isinstance(api_content, bytes):
        api_content = api_content.decode('utf-8')
    api_result = json.loads(api_content)['result']
    if api_result != 1:
        logger.error('===api_result!=1===')
        logger.error('===api content:%s===', api_content)
    else:
        logger.info('===api content:%s===', api_content)

def check_success(settings):
    """通过查询数据库holding和trade的数据，判断当日数据是否处理成功
    :return:
    """
    mysql_settings = settings.mysql_conf
    MYSQL_HOST = mysql_settings['MYSQL_HOST']
    MYSQL_PORT = mysql_settings['MYSQL_PORT']
    MYSQL_DB = mysql_settings['MYSQL_DB']
    MYSQL_USER = mysql_settings['MYSQL_USER']
    MYSQL_PASSWD = mysql_settings['MYSQL_PASSWD']
    MYSQL_CHARTSET = mysql_settings['MYSQL_CHARTSET']

    db = pymysql.connect(
        host=MYSQL_HOST,
        port=MYSQL_PORT,
        database=MYSQL_DB,
        user=MYSQL_USER,
        password=MYSQL_PASSWD,
        charset=MYSQL_CHARTSET)
    cursor = db.cursor()

    yesterday_date=datetime.datetime.now().date()+datetime.timedelta(days=-1)
    yesterday_date_str=str(yesterday_date)

    trade_select_sql="SELECT DISTINCT `date` FROM `ark_trade` ORDER BY date DESC LIMIT 1;"
    holding_select_sql = "SELECT DISTINCT `date` FROM `ark_holdings` ORDER BY date DESC LIMIT 1;"

    cursor.execute(trade_select_sql)
    trade_newdate=cursor.fetchone()[0]

    cursor.execute(holding_select_sql)
    holding_newdate = cursor.fetchone()[0]

    flag=False
    if trade_newdate==yesterday_date_str and holding_newdate==yesterday_date_str:#如果这2个数据的数据都是最新的，则当日数据更新成功
        flag=True

    cursor.close()
    db.close()

    return flag

if __name__=='__main__':
    # 获取本机计算机名称
    hostname = socket.gethostname()
    # 获取本机ip
    ip = socket.gethostbyname(hostname)
    if ip == '10.0.11.251':  # 如果是阿里云火车头服务器的ip，则存入生产数据库
        setting_hostname = 'jyb_mysql'
        is_request = True
    else:
        setting_hostname = '96_mysql'
        is_request = False
    settings = my_settings.mysqlSettings(hostname=setting_hostname)

    # 日志配置
    curr_path = os.getcwd() + '/'
    start_date_str = str(time.strftime('%Y-%m-%d_%H', time.localtime()))
    month_str = start_date_str[:7]
    main_log_path = curr_path + 'main_run_logs/' + month_str
    if not os.path.exists(main_log_path): os.makedirs(main_log_path)
    log_filename = main_log_path + '/' + Path(__file__).name.replace('.py', '') + '_%s.log' % start_date_str
    log_rank = logging.INFO
    logger = log_process(log_filename, log_rank)

    logger.info('**********************************************')
    logger.info('***ip:%s', ip)
    logger.info('***mysql setting_hostname:%s', setting_hostname)
    logger.info('**********************************************')


    today_str = str(time.strftime('%Y%m%d', time.localtime()))
    fin_result_holding=open('ArkSpider_result_holding.txt','r',encoding='utf-8')
    result_holding=fin_result_holding.read().replace('\ufeff','').strip().split(':')
    holding_result_date = result_holding[0]
    holding_result_flag = result_holding[1]

    if holding_result_date==today_str and holding_result_flag=='True':
        print('ArkSpider_holding_result不用再处理...')
        logger.info('===今日ArkSpider holding数据已经成功处理完毕，不需要再处理===')
    else:
        print('开始处理ArkSpider_holding...')
        #ark_trade
        email_spider = ark_email_spider(logger=logger,settings=settings)
        email_spider.run_add_all_email()
        # trade_temp=open('2021-08-20.txt','r',encoding='utf-8').readlines()
        # trade_temp=[line.replace('\ufeff','').strip() for line in trade_temp]
        # trade_temp=[line.split(',') for line in trade_temp]
        # email_spider.insert_mysql(trade_temp)
        logger.info('===ark_trade done===')
        logger.info('===ark_trade run_flag=%s',email_spider.run_flag)

        #ark_holding
        holding_spider = ark_webholding_spider(logger=logger,settings=settings)
        holding_date_complete_flag,uncomplete_data_date=holding_spider.run()
        logger.info('===ark_holding done===')
        logger.info('===holding_spider.run_flag=%s,ark_holding holding_date_complete_flag=%s',holding_spider.run_flag,holding_date_complete_flag)

        temp_today_str = str(time.strftime('%Y%m%d', time.localtime()))
        api_url = 'http://cloudapi.iqdii.com/arkTracking/ark/deleteArkCache?ark=' + temp_today_str

        if holding_date_complete_flag:
            #run sql
            rs = run_sql(logger=logger,settings=settings)
            rs.execute_sql()
            logger.info('===run_sql done===')
            logger.info('===run_sql run_flag=%s',rs.run_flag)

            if is_request:#生产的才需要做这个请求
                # 如果trade、holding、run_sql这三个模块都运行成功，则请求一次生产的http接口，表示可以更新缓存数据
                if email_spider.run_flag and rs.run_flag and holding_spider.run_flag:
                    #http://cloudapi.iqdii.com/arkTracking/ark/deleteArkCache?ark=20210629
                    get_api(logger,info='trade holding run_sql模块')
                else:
                    logger.error('===trade、holding、run_sql其中有运行异常，没有请求生产http===')
                    logger.error('trade->run_flag=%s,holding_spider->run_flag=%s,holding_date_complete_flag=%s,run_sql->run_flag=%s',email_spider.run_flag,holding_spider.run_flag,holding_date_complete_flag,
                                 rs.run_flag)
        else:
            logger.warning('===!!!本次ark_holding 数据不完整,不完整的数据为：%s',str(uncomplete_data_date))

        fout_result_holding = open('ArkSpider_result_holding.txt', 'w', encoding='utf-8')  # 记录当日数据是否处理成功
        # 判断是否成功处理当日数据
        success_flag = check_success(settings)
        if success_flag:  # 若成功处理当日数据，则记录，且发邮件通知相关同事
            print('holding模块数据处理成功...')
            if is_request:  #只有生产环境的才需要发邮件通知同事是否处理成功
                print('发送邮件给相关同事，通知APP数据已更新...')
                start_time_str = str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
                email_subject = 'ark_project:%s' % start_time_str
                email_content_list = [email_subject+'Ark的数据处理成功，APP前端已更新。\n']
                logger_info = '当天数据处理成功，已发邮件通知相关同事...'
                # success_receiver = ["zoey.yang@tradego8.com"]
                success_receiver = ["zoey.yang@tradego8.com","albert.lee@tradego8.com",
                                    "perry.huang@tradego8.com"]
                send_email(email_subject, email_content_list, logger, logger_info, success_receiver)

            fout_result_holding.write(today_str + ':' + 'True')  # 文档记录当天数据已经成功处理，下次就不用再处理了
        else:
            print('holding模块数据处理有错误...')
            fout_result_holding.write(today_str + ':' + 'False')
        fout_result_holding.close()

    # 发错误提醒邮件
    print('日志邮件处理...')
    start_time_str = str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
    email_subject = 'ark_project_%s' % start_time_str
    email_content_list = []
    log_content = open(log_filename, 'r', encoding='utf-8').readlines()
    for line in log_content:
        if '- ERROR:' in line:
            email_content_list.append(line)

    fin=open('日志_email.txt','r',encoding='utf-8')
    log_email=fin.readlines()
    log_email_count=0
    if log_email:
        for line in log_email:
            line=line.split(':')
            log_email_date=line[0]
            # log_email_info=line[1]
            if log_email_date==today_str:
                log_email_count+=1
            #20210803:发送日志错误邮件预警一次
    fin.close()
    # 有错误日志，则发邮件
    if email_content_list:
        if log_email_count>2:
            print('===运行有错误，日志已发送过2次，不再发送日志提醒')
            logger.info('===运行有错误，日志已发送过2次，不再发送日志提醒')
        else:
            error_log_receiver = ["zoey.yang@tradego8.com"]
            logger_info = '错误日志邮件提醒'
            send_email(email_subject, email_content_list, logger, logger_info, error_log_receiver)
            logger.info('===发送了日志错误邮件提醒===')
            print('===运行有错误，发送了日志错误邮件提醒===')

            fout_log_email=open('日志_email.txt','a',encoding='utf-8')
            fout_log_email.write(today_str+':发送日志错误邮件预警一次\n')
            fout_log_email.close()
    else:
        logger.info('===没有发现有错误日志，不需要发送邮件===')
        print('===没有发现有错误日志，不需要发送邮件===')

    #开始处理fundflow程序
    fin_result_fundflow = open('ArkSpider_result_fundflow.txt', 'r', encoding='utf-8')
    result_fundflow = fin_result_fundflow.read().replace('\ufeff', '').strip().split(':')
    result_fundflow_date = result_fundflow[0]
    result_fundflow_flag = result_fundflow[1]

    # ark_fundvaluecashintout
    if result_fundflow_date==today_str and result_fundflow_flag=='True':
        print('不用处理ark_fundvaluecashintout...')
        logger.info('===今日ArkSpider fundflow数据已经成功处理完毕，不需要再处理===')
    else:
        print('开始处理ark_fundvaluecashintout...')
        fundflow_spider = ark_fundflow_spider(logger=logger, settings=settings)
        fundflow_spider.run()
        logger.info('===ark_fundvaluecashintout done===')

        fout_result_fundflow=open('ArkSpider_result_fundflow.txt', 'w', encoding='utf-8')
        if fundflow_spider.run_flag:
            if is_request:
                print('fundflow处理成功,3分钟后调用api...')
                for i in tqdm(range(180), ncols=50):
                    time.sleep(1)  # 3分钟后调用api
                get_api(logger, info='ark_fundvaluecashintout模块')
            fout_result_fundflow.write(today_str + ':' + 'True')
            print('========ark_fundvaluecashintout模块处理成功===')
        else:
            logger.error('========%s,ark_fundvaluecashintout模块有错误', fundflow_spider.run_flag)
            print('========ark_fundvaluecashintout模块处理失败...')
            fout_result_fundflow.write(today_str + ':' + 'False')

        fout_result_fundflow.close()

    print('main_run.py本次运行结束...')


